package com.springboot.webdemo.dao;


import com.springboot.webdemo.core.result.Pager;
import com.springboot.webdemo.core.utils.CommonUtil;
import org.apache.ibatis.session.SqlSessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Repository
public abstract class BaseDaoImpl<T, PK extends Serializable> extends
		SqlSessionDaoSupport implements BaseDao<T, PK> {

	public static Logger logger = LoggerFactory.getLogger(BaseDaoImpl.class);

	private Class<T> entityClass = null;

	/**
	 * 创建默认构造方法，以取得真正的泛型类型
	 * 
	 * @author javaing(www.javaing.net)
	 */
	public BaseDaoImpl() {
		Class<?> c = getClass();
		Type type = c.getGenericSuperclass();
		if (type instanceof ParameterizedType) {
			Type[] parameterizedType = ((ParameterizedType) type).getActualTypeArguments();
			entityClass = (Class<T>) parameterizedType[0];
		}
	}

	@Resource(name = "sqlSessionFactory")
	public void setSuperSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
		super.setSqlSessionFactory(sqlSessionFactory);
	}

	/**
	 * 以下方法统一使用默认mybatis映射xml文件的sql标识
	 * 说明：默认mapper namespace为entity类的全局名称，对应的mapperId为对应的方法名称
	 */

	/**
	 * 保存实体
	 * @param entity
	 * @return
	 */
	public T insert(T entity) {
		getSqlSession().insert(entity.getClass().getName() + ".insert",
				entity);
		return entity;

	}

	/**
	 * 批量插入记录
	 * @param entities 要保存的数据集合
	 * @return
	 */
	public List<T> insertList(List<T> entities) {
		if(CommonUtil.listIsNull(entities)) {
			return entities;
		}
		this.getSqlSession().insert(entityClass.getName() + ".insertList", entities);
		return entities;
	}

	/**
	 * 更新
	 * @param entity
	 */
	public void update(T entity) {

		getSqlSession().update(entity.getClass().getName() + ".update",
				entity);
	}

	/**
	 * 批量更新
	 * @param entities
	 */
	@Override
	public void updateList(List<T> entities){
		getSqlSession().update(entityClass.getName() + ".updateList",entities);
	}


	/**
	 * 清空表内容
	 * @author zhangfp
	 */
	@Override
	public void delete(){
		getSqlSession().delete(entityClass.getName() + ".delete");
	}

	/**
	 * 根据id删除某个对象
	 * @param id 主键ID
 	 */
	public void deleteById(PK id) {
		getSqlSession().delete(entityClass.getName() + ".deleteById", id);
	}


	/**
	 * 根据id加载某个对象
	 * @param id
	 * @return
	 */
	public T fetch(PK id) {
		return getSqlSession().selectOne(
				entityClass.getName() + ".fetch", id);

	}

	/**
	 * 查找所有的对象
	 * @return
	 */
	public List<T> findAll() {
		return getSqlSession().selectList(
				entityClass.getName() + ".findAll", null);

	}

	/**
	 * 根据条件查询总数
	 * @param condition
	 * @return
	 */
	public int count(Map<String, Object> condition) {

		int count = getSqlSession().selectOne(
				entityClass.getName() + ".count", condition);
		return count;

	}

	/**
	 *  根据查询参数，当前页数，每页显示的数目得到分页列表
	 *
	 * @param condition
	 *            查询条件
	 * @param currentPage
	 *            当前页数
	 * @param pageSize
	 *            页面大小
	 * @return
	 */

	public Pager<T> queryPage(Map<String, Object> condition,
			Integer currentPage, Integer pageSize) {
		Pager<T> pager = new Pager<T>(pageSize, count(condition), currentPage);
		try {
			if (condition == null) {
				condition = new HashMap<String, Object>();
			}
			condition.put("beginRow",
					(pager.getCurrentPage() - 1) * pager.getPageSize());

			condition.put("pageSize", pager.getPageSize());

			List<T> dataList = this.getSqlSession().selectList(
					entityClass.getName() + ".queryPage", condition);

			pager.setDataList(dataList);
			return pager;
		} catch (RuntimeException re) {
			logger.error("queryPage " + entityClass.getName() + "failed :{}", re);
		}
		return null;
	}

	/**
	 * 分页查询返回结果为Map对象的实现
	 *
	 * @author zhangfp
	 *
	 * @param condition
	 * @param currentPage
	 * @param pageSize
	 * @return
	 */
	@Override
	public Pager<Map<String,Object>> queryPageMap(Map<String,Object> condition,Integer currentPage,Integer pageSize){
		Pager<Map<String,Object>> pager = new Pager<Map<String,Object>>(pageSize, count(condition), currentPage);
		try {
			if (condition == null) {
				condition = new HashMap<String, Object>();
			}
			condition.put("beginRow",
					(pager.getCurrentPage() - 1) * pager.getPageSize());

			condition.put("pageSize", pager.getPageSize());

			List<Map<String,Object>> dataList = this.getSqlSession().selectList(
					entityClass.getName() + ".queryPageMap", condition);

			pager.setDataList(dataList);
			return pager;
		} catch (RuntimeException re) {
			logger.error("queryPage " + entityClass.getName() + "failed :{}", re);
		}
		return null;
	}
	/**
	 * 指定mapperId分页查询返回结果为Map对象的实现
	 * @author chenzy
	 * @return
	 */
	@Override
	public Pager<Map<String,Object>> queryPageMap(String mapperId, Map<String, Object> condition,
										   Integer currentPage, Integer pageSize){
		Pager<Map<String,Object>> pager = new Pager<Map<String,Object>>(pageSize,count(mapperId+"Count",condition),currentPage);
		try {
			if (condition == null) {
				condition = new HashMap<String, Object>();
			}
			condition.put("beginRow",
					(pager.getCurrentPage() - 1) * pager.getPageSize());
			condition.put("pageSize", pager.getPageSize());
			List<Map<String,Object>> dataList = this.getSqlSession().selectList(
					entityClass.getName() + "." + mapperId, condition);
			pager.setDataList(dataList);
			return pager;
		} catch (RuntimeException re) {
			logger.error("queryPage " + entityClass.getName() + "failed :{}", re);
		}
		return null;
	}

	/**
	 * 指定mapperId查询总数
	 * @param mapperId
	 * @param condition
	 * @return
	 */
	public int count(String mapperId, Map<String, Object> condition) {

		int count = getSqlSession().selectOne(
				entityClass.getName() + "." + mapperId, condition);
		return count;

	}

	/**
	 * 指定mapperId分页查询
	 * @param mapperId
	 * @param condition
	 * @param currentPage
	 * @param pageSize
	 * @return
	 */
	public Pager<T> queryPage(String mapperId,Map<String,Object> condition,
							  Integer currentPage,Integer pageSize){
		Pager<T> pager = new Pager<T>(pageSize,count(mapperId+"Count",condition),currentPage);
		try {
			if (condition == null) {
				condition = new HashMap<String, Object>();
			}
			condition.put("beginRow",
					(pager.getCurrentPage() - 1) * pager.getPageSize());
			condition.put("pageSize", pager.getPageSize());
			List<T> dataList = this.getSqlSession().selectList(
					entityClass.getName() + "." + mapperId, condition);
			pager.setDataList(dataList);
			return pager;
		} catch (RuntimeException re) {
			logger.error("queryPage " + entityClass.getName() + "failed :{}", re);
		}
		return null;
	}
	/**
	 * 条件查询，并提供排序 返回结果为Map
	 * @param condition
	 *            进行查询的条件集合
	 * @param orderBy 排序字段
	 * @param sortBy  排序类型（升序或降序）
	 * @return
	 */
	@Override
	public List<Map<String, Object>> queryListMap(Map<String, Object> condition, String orderBy,
							 String sortBy) {

		if (condition == null) {
			condition = new HashMap<String, Object>();
			condition.put("orderBy", orderBy);
			condition.put("sortBy", sortBy);
		}else {
			condition.put("orderBy", orderBy);
			condition.put("sortBy", sortBy);
		}

		return getSqlSession().selectList(
				entityClass.getName() + ".queryListMap", condition);

	}

	/**
	 * 条件查询，并提供排序
	 * @param condition
	 *            进行查询的条件集合
	 * @param orderBy 排序字段
	 * @param sortBy  排序类型（升序或降序）
	 * @return
	 */
	public List<T> queryList(Map<String, Object> condition, String orderBy,
			String sortBy) {

		if (condition == null) {
			condition = new HashMap<String, Object>();

			condition.put("orderBy", orderBy);
			condition.put("sortBy", sortBy);
		}else {
			condition.put("orderBy", orderBy);
			condition.put("sortBy", sortBy);
		}
		return getSqlSession().selectList(
				entityClass.getName() + ".queryList", condition);

	}

	/**
	 * 查询一条记录
	 * @param condition
	 *            进行查询的条件集合
	 * @return
	 */
	public T queryOne(Map<String, Object> condition) {
		return getSqlSession().selectOne(entityClass.getName() + ".queryOne", condition);
	}

	/**
	 * 更新或保存
	 * @param t
	 *            要更新或保存的对象
	 * @param id
	 *            要更新或保存的对象的id
	 * @return
	 */
	public T updateOrSave(T t, PK id) {
		if (null != fetch(id)) {
			update(t);
		} else {
			return insert(t);
		}
		return t;
	}

	/**
	 * 条件删除
	 * @param condition
	 */
	public void deleteByCondition(Map<String, Object> condition) {
		getSqlSession().delete(entityClass.getName() + ".deleteByCondition", condition);
	}
	
	/**
	 * 批量删除
	 * @param entities
	 */
	public void deleteList(List<Integer> entities) {
		getSqlSession().delete(entityClass.getName() + ".deleteList",entities);
	}

	/**
	 * 批量删除
	 * @param entities
	 */
	@Override
	public void deleteBatch(List<T> entities) {
		getSqlSession().delete(entityClass.getName() + ".deleteBatch",entities);
	}
	@Override
	public int deleteByIds(PK[] ids) {
		return getSqlSession().delete(entityClass.getName()+".deleteByIds", ids);
		
	}

	public Class<T> getEntityClass() {
		return entityClass;
	}
}
